package org.framework.common.cui;

import java.util.List;

import org.framework.common.api.entity.CommonEntityAware;
import org.framework.common.api.support.model.FormModel;
import org.framework.common.api.support.model.ProcedureModel;
import org.framework.common.api.support.model.QueryModel;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 公共服务类.<br>
 * 包含：<br>
 * 1、页面寻址的跳转控制<br>
 * 2、CRUD请求控制
 * <p>描述:</p>
 * <p>Company:上海中信信息发展股份有限公司</p>
 * @author chanlong(陈龙)
 * @date 2014年10月29日  上午10:23:30
 * @version 1.0.2014.
 */
@RestController
public class CommonContoller extends AbstractController{
	
	/**
	 * 获取树结构数据.
	 * @param dbname
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2016年3月29日 下午6:38:37
	 */
	@RequestMapping("/{dbname}/common/tree.json")
	public Object tree(@PathVariable final String dbname, @ModelAttribute final QueryModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("查询失败，请检查数据源或参数绑定源。");
				
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 查询实体对象
			return bo.tree(model);
		} catch (Exception e) {
			return error("获取树信息失败！", e);
		}
	}
	
	/**
	 * 获取下拉框数据.
	 * @param dbname
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2016年2月8日 下午6:16:58
	 */
	@RequestMapping("/{dbname}/common/select.json")
	public Object select(@PathVariable final String dbname, @ModelAttribute final FormModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("查询失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 查询实体对象
			return bo.select(model);
		} catch (Exception e) {
			return error("获取下拉框数据失败！", e);
		}
	}
	
	/**
	 * 加载实体对象.
	 * @param dbo
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2014年7月11日  下午3:40:06
	 */
	@RequestMapping("/{dbname}/common/loader.json")
	public Object loader(@PathVariable final String dbname, @ModelAttribute final FormModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("加载失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 获取实体对象
			CommonEntityAware<String> entity = model.getEntity();
			
			// 加载实体对象
			return bo.loader(entity);
		} catch (Exception e) {
			return error("加载实体对象失败！", e);
		}
	}
	
	/**
	 * 查询（关联查询时推荐使用视图）.
	 * @param dbo
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2014年8月4日  下午3:35:43
	 */
	@RequestMapping("/{dbname}/common/search.json")
	public Object search(@PathVariable final String dbname, @ModelAttribute final QueryModel query) throws Exception {
		// 参数检查
		if (check(dbname) && check(query)) return error("查询失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);

			// 返回查询结果
			return bo.findByQuery(query);
		} catch (Exception e) {
			e.printStackTrace();
			return error("查询实体对象失败！", e);
		}
	}
	
	/**
	 * 新增实体对象.
	 * @param dbo
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2014年7月11日  下午3:54:58
	 */
	@RequestMapping("/{dbname}/common/save")
	public Object create(@PathVariable final String dbname, @ModelAttribute final FormModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("新增失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 获取实体对象
			List<CommonEntityAware<String>> entities = model.getEntities();

			// 保存实体对象
			if(entities != null && !entities.isEmpty()){
				return bo.insertAll(entities);
			}else{
				CommonEntityAware<String> entity = model.getEntity();
				return bo.insert(entity);
			}
		}catch(Exception e){
			return error("新增实体对象失败！", e);
		}
	}
	
	/**
	 * 修改实体对象.
	 * @param dbo
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2014年7月28日  下午4:14:18
	 */
	@RequestMapping("/{dbname}/common/update")
	public Object update(@PathVariable final String dbname, @ModelAttribute final FormModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("更新失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 获取实体对象
			CommonEntityAware<String> entity = model.getEntity();
			
			// 更新实体对象
			return bo.update(entity);
		}catch(Exception e){
			return error("更新实体对象失败！", e);
		}
	}
	
	/**
	 * 删除实体对象（逻辑删除）.
	 * @param dbo
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2014年7月28日  下午4:14:52
	 */
	@RequestMapping("/{dbname}/common/delete")
	public Object delete(@PathVariable final String dbname, @ModelAttribute final FormModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("删除失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 获取实体对象
			CommonEntityAware<String> entity = model.getEntity();
			
			// 更新实体对象
			bo.update(entity);
			
			return success("删除实体对象成功！");
		}catch(Exception e){
			return error("删除实体对象失败！", e);
		}
	}
	
	/**
	 * 删除实体对象（物理删除）.
	 * @param dbo
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2014年7月28日  下午4:16:04
	 */
	@RequestMapping("/{dbname}/common/remove")
	public Object remove(@PathVariable final String dbname, @ModelAttribute final FormModel model) throws Exception {
		// 参数检查
		if (check(dbname) && check(model)) return error("删除失败，请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 获取实体对象
			CommonEntityAware<String> entity = model.getEntity();
			
			// 删除实体对象
			bo.delete(entity);
			
			return success("删除实体对象成功！");
		}catch(Exception e){
			return error("删除实体对象失败！", e);
		}
	}
	
	/**
	 * 调用存储过程.
	 * @param dbname
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2016年9月7日 下午6:25:02
	 */
	@RequestMapping("/{dbname}/common/procedure/call")
	public Object call(@PathVariable final String dbname, @ModelAttribute final ProcedureModel model) throws Exception {
		// 参数检查
		if (check(dbname)) return error("请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 调用存储过程
			return model.call(jdbc);
		} catch (Exception e) {
			e.printStackTrace();
			return error("报表统计失败！", e);
		}
	}
	
	/**
	 * 导出存储过程数据.
	 * @param dbname
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2016年9月7日 下午6:25:02
	 */
	@RequestMapping("/{dbname}/common/procedure/export")
	public Object export(@PathVariable final String dbname, @ModelAttribute final ProcedureModel model) throws Exception {
		// 参数检查
		if (check(dbname)) return error("请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 创建响应头
			HttpHeaders headers = new HttpHeaders();
	        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
	        headers.setContentDispositionFormData("attachment", new String((model.getName()+".xlsx").getBytes("utf-8"), "ISO8859-1"));  
	        
	        // 返回文件下载流
	        return new ResponseEntity<byte[]>(model.export(response), headers, HttpStatus.CREATED);
		} catch (Exception e) {
			e.printStackTrace();
			return error("导出报表失败！", e);
		}
	}
	
	/**
	 * 统计图表.
	 * @param dbname
	 * @param model
	 * @return
	 * @throws Exception
	 * @author chanlong(陈龙)
	 * @date 2016年9月7日 下午6:25:02
	 */
	@RequestMapping("/{dbname}/common/procedure/charts")
	public Object charts(@PathVariable final String dbname, @ModelAttribute final ProcedureModel model) throws Exception {
		// 参数检查
		if (check(dbname)) return error("请检查数据源或参数绑定源。");
		
		try{
			// 注册数据源
			registerDataSource(dbname);
			
			// 返回图表统计结果
	        return model.charts(jdbc);
		} catch (Exception e) {
			e.printStackTrace();
			return error("导出报表失败！", e);
		}
	}
}
